package com.sicpa.system.service.impl;

import cn.hutool.core.io.resource.ClassPathResource;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sicpa.common.config.SicpaConfig;
import com.sicpa.common.constant.HttpStatus;
import com.sicpa.common.constant.ReportFormTypeConstants;
import com.sicpa.common.core.domain.AjaxResult;
import com.sicpa.common.core.domain.entity.AntiCounterfeitingRegisteredOffice;
import com.sicpa.common.core.domain.entity.AssuranceBusinessDataRegisterSignature;
import com.sicpa.common.core.page.TableDataInfo;
import com.sicpa.system.mapper.AntiCounterfeitingRegisteredOfficeMapper;
import com.sicpa.system.mapper.AssuranceBusinessDataRegisterSignatureMapper;
import com.sicpa.system.mapper.AssuranceBusinessDataReportMapper;
import com.sicpa.system.service.IAssuranceBusinessReportFormService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName:报表接口
 * @author: zf
 * @description: 报表接口service层实现
 * @date 2020/9/15
 */
@Service
public class AssuranceBusinessReportFormServiceImpl implements IAssuranceBusinessReportFormService {

    private static final Logger log = LoggerFactory.getLogger(AssuranceBusinessReportFormServiceImpl.class);

    private AntiCounterfeitingRegisteredOfficeMapper antiCounterfeitingRegisteredOfficeMapper;

    private AssuranceBusinessDataReportMapper assuranceBusinessDataReportMapper;

    private AssuranceBusinessDataRegisterSignatureMapper assuranceBusinessDataRegisterSignatureMapper;

    @Autowired
    public AssuranceBusinessReportFormServiceImpl(AntiCounterfeitingRegisteredOfficeMapper antiCounterfeitingRegisteredOfficeMapper, AssuranceBusinessDataReportMapper assuranceBusinessDataReportMapper, AssuranceBusinessDataRegisterSignatureMapper assuranceBusinessDataRegisterSignatureMapper) {
        this.antiCounterfeitingRegisteredOfficeMapper = antiCounterfeitingRegisteredOfficeMapper;
        this.assuranceBusinessDataRegisterSignatureMapper = assuranceBusinessDataRegisterSignatureMapper;
        this.assuranceBusinessDataReportMapper = assuranceBusinessDataReportMapper;
    }

    /**
     * 获取报表 表格数据
     *
     * @param query 查询条件 type 报表的类型
     * @return、
     */
    @Override
    public TableDataInfo getAssureanceReportFormData(HashMap<String, Object> query) {
        String type = query.get("type").toString();
        TableDataInfo tableDataInfo;
        switch (type) {
            case ReportFormTypeConstants.REPORT_TYPE_1:
                tableDataInfo = getAssureanceOffisce(query);
                break;
            case ReportFormTypeConstants.REPORT_TYPE_2:
                tableDataInfo = getRegisterDataByReportType(query);
                break;
            case ReportFormTypeConstants.REPORT_TYPE_3:
                tableDataInfo = getAssuranceNumByOpinion(query);
                break;
            case ReportFormTypeConstants.REPORT_TYPE_4:
                tableDataInfo = getRegisterNumByOpinion(query);
                break;
            case ReportFormTypeConstants.REPORT_TYPE_5:
                tableDataInfo = getAssuranceNumBySecurities(query);
                break;
            case ReportFormTypeConstants.REPORT_TYPE_6:
                tableDataInfo = getRegisterNumBySecurities(query);
                break;
            case ReportFormTypeConstants.REPORT_TYPE_7:
                //更换事务所统计
                tableDataInfo = selectCustomerReportData(query);
                break;
            case ReportFormTypeConstants.REPORT_TYPE_8:
                //根据注师汇总报告-报告数量畸多
                tableDataInfo = selectRegisterReportData(query);
                break;
            default:
                tableDataInfo = new TableDataInfo();
                break;
        }
        return tableDataInfo;
    }

    /**
     * 获取报表 表格的表头
     *
     * @param query 查询条件 type 报表的类型
     * @return
     */
    @Override
    public HashMap<String, Object> getAssureanceReportFormTabel(HashMap<String, Object> query) throws IOException {
        HashMap<String, Object> result = new HashMap<>();
        String type = query.get("type").toString();
        ClassPathResource resource = new ClassPathResource("reportForm.json");
        InputStream in = resource.getStream();
        try {
            //读取文件
            JSONObject jsonObject = JSON.parseObject(in, JSONObject.class);
            JSONObject re = (JSONObject) jsonObject.get(type);
            result = new HashMap<>(re);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 下载报表表单
     *
     * @param query
     */
    @Override
    public AjaxResult downloadReportForm(HashMap<String, Object> query) throws Exception {
        TableDataInfo tableDataInfo = getAssureanceReportFormData(query);
        String type = query.get("type").toString();
        return downloadReportForm(type, tableDataInfo.getRows());
    }

    /**
     * 导出
     *
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    private AjaxResult downloadReportForm(String sheetName, List list) throws Exception {
        ClassPathResource classPathResource = new ClassPathResource("excel/报告数据查询需求.xlsx");
        InputStream inputStream = classPathResource.getStream();
        //创建工作簿
        XSSFWorkbook templateWb = new XSSFWorkbook(inputStream);
        Iterator<Sheet> it = templateWb.iterator();
        while (it.hasNext()) {
            Sheet sheet = it.next();
            String sheetSheetName = sheet.getSheetName();
            if (!StringUtils.equals(sheet.getSheetName(), sheetName)) {
                int sheetIndex = templateWb.getSheetIndex(sheetSheetName);
                templateWb.removeSheetAt(sheetIndex);
                it = templateWb.iterator();
            }
        }
        XSSFSheet templateSheet = templateWb.getSheet(sheetName);
        int physicalNumberOfRows = templateSheet.getPhysicalNumberOfRows();
        if (list != null) {
            for (Object item : list) {
                HashMap<String, Object> tem = (HashMap<String, Object>) item;
                XSSFRow xssfRow = templateSheet.createRow(physicalNumberOfRows);
                Iterator iter = tem.entrySet().iterator();
                AtomicInteger count = new AtomicInteger(0);
                while (iter.hasNext()) {
                    XSSFCell xssfCell = xssfRow.createCell(count.get());
                    Map.Entry entry = (Map.Entry) iter.next();
                    if (entry != null && entry.getValue() != null) {
                        xssfCell.setCellValue(entry.getValue().toString());
                    }
                    count.getAndIncrement();
                }
                count.set(0);
                physicalNumberOfRows++;
            }
        }
        OutputStream out = null;
        String fileName = UUID.randomUUID().toString() + "_" + sheetName + ".xlsx";
        try {
            out = new FileOutputStream(getAbsoluteFile(fileName));
            templateWb.write(out);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
        return AjaxResult.success(fileName);
    }

    /**
     * 获取下载路径
     *
     * @param filename 文件名称
     */
    private String getAbsoluteFile(String filename) {
        String downloadPath = SicpaConfig.getDownloadPath() + filename;
        File desc = new File(downloadPath);
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        return downloadPath;
    }

    /**
     * 获取 报备情况-按所统计 报表
     *
     * @return
     */
    public TableDataInfo getAssureanceOffisce(HashMap<String, Object> queryParam) {
        List< LinkedHashMap<String, Object>> result = new ArrayList<>();
        HashMap<String, Object> firmNameQuery = getFirmNameQuery(queryParam);
        startPage(queryParam);
        List<AntiCounterfeitingRegisteredOffice> list = antiCounterfeitingRegisteredOfficeMapper.selectReportOfficeOrderByNum(firmNameQuery);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<Long> officeIdList = new ArrayList<>();
        getFirmNameTableData(list,result,officeIdList);
        HashMap<String, Object> query = new HashMap<>();
        query.put("startTime", queryParam.get("startTime").toString());
        query.put("endTime", queryParam.get("endTime").toString());
        query.put("officeIdList",officeIdList);
        List<HashMap<String, Object>> reportList = assuranceBusinessDataReportMapper.getAssuranceNumByType(query);
        getOfficeReportTypeData(reportList,result);
        tableDataInfo.setRows(result);
        return tableDataInfo;
    }

    private  HashMap<String, Object> getFirmNameQuery(HashMap<String, Object> queryParam){
        HashMap<String, Object> firmNameQuery = new HashMap<>();
        if (queryParam.containsKey("firmName")) {
            firmNameQuery.put("firmName", queryParam.get("firmName").toString());
        }
        if (queryParam.containsKey("startTime") && queryParam.containsKey("endTime")) {
            firmNameQuery.put("startTime", queryParam.get("startTime").toString());
            firmNameQuery.put("endTime", queryParam.get("endTime").toString());
        }
        return firmNameQuery;
    }

    private void getFirmNameTableData( List<AntiCounterfeitingRegisteredOffice> list,List< LinkedHashMap<String, Object>> result,List<Long> officeIdList){
        for (int i = 0; i < list.size(); i++) {
            AntiCounterfeitingRegisteredOffice office = list.get(i);
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            map.put("id",i+1);
            map.put("practiceCertificateNo", office.getPracticeCertificateNo());
            map.put("firmName", office.getFirmName());
            officeIdList.add(office.getOfficeId());
            result.add(map);
        }
    }

    /**
     * 报备情况-按CPA统计 报表
     *
     * @return
     */
    public TableDataInfo getRegisterDataByReportType(HashMap<String, Object> queryParam) {
        List< LinkedHashMap<String, Object>> result = new ArrayList<>();
        HashMap<String, Object> firmNameQuery = getRegisterQuery(queryParam);
        startPage(queryParam);
        List<AssuranceBusinessDataRegisterSignature> list = assuranceBusinessDataRegisterSignatureMapper.selectRegisterListByGroup(firmNameQuery);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<String> registrationCertificateNoList = new ArrayList<>();
        getRegisterTableData(list,result,registrationCertificateNoList);
        HashMap<String, Object> query = new HashMap<>();
        query.put("startTime", queryParam.get("startTime").toString());
        query.put("endTime", queryParam.get("endTime").toString());
        query.put("registrationCertificateNoList",registrationCertificateNoList);
        List<HashMap<String, Object>> reportList = assuranceBusinessDataReportMapper.getRegisterNumByType(query);
        getRegistrantReportTypeData(reportList, result);
        tableDataInfo.setRows(result);
        return tableDataInfo;
    }

    private  HashMap<String, Object> getRegisterQuery(HashMap<String, Object> queryParam){
        HashMap<String, Object> firmNameQuery = new HashMap<>();
        if (queryParam.containsKey("registrantName")) {
            firmNameQuery.put("registrantName",queryParam.get("registrantName").toString());
        }
        if (queryParam.containsKey("startTime") && queryParam.containsKey("endTime")) {
            firmNameQuery.put("startTime", queryParam.get("startTime").toString());
            firmNameQuery.put("endTime", queryParam.get("endTime").toString());
        }
        return firmNameQuery;
    }

    private void getRegisterTableData(List<AssuranceBusinessDataRegisterSignature> list,List< LinkedHashMap<String, Object>> result, List<String> registrationCertificateNoList){
        for (int i = 0; i < list.size(); i++) {
            AssuranceBusinessDataRegisterSignature assuranceBusinessDataRegisterSignature2 = list.get(i);
            registrationCertificateNoList.add(assuranceBusinessDataRegisterSignature2.getRegistrationCertificateNo());
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            map.put("id",i+1);
            map.put("registrantName", assuranceBusinessDataRegisterSignature2.getRegistrantName());
            map.put("registrationCertificateNo", assuranceBusinessDataRegisterSignature2.getRegistrationCertificateNo());
            map.put("firmName", assuranceBusinessDataRegisterSignature2.getFirmName());
            result.add(map);
        }
    }


    /**
     * 获取 审计意见类型-按所统计 报表
     *
     * @return
     */
    public TableDataInfo getAssuranceNumByOpinion(HashMap<String, Object> queryParam) {
        List<LinkedHashMap<String, Object>> result = new ArrayList<>();
        HashMap<String, Object> firmNameQuery = getFirmNameQuery(queryParam);
        startPage(queryParam);
        List<AntiCounterfeitingRegisteredOffice> list = antiCounterfeitingRegisteredOfficeMapper.selectReportOffice(firmNameQuery);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<Long> officeIdList = new ArrayList<>();
        getFirmNameTableData(list,result,officeIdList);
        HashMap<String, Object> query = new HashMap<>();
        query.put("officeIdList",officeIdList);
        query.put("startTime", queryParam.get("startTime").toString());
        query.put("endTime", queryParam.get("endTime").toString());
        List<HashMap<String, Object>> reportList = assuranceBusinessDataReportMapper.getAssuranceNumByOpinion(query);
        getOfficeOpinionData(reportList, result);
        tableDataInfo.setRows(result);
        return tableDataInfo;
    }

    /**
     * 审计意见类型-按CPA统计 报表
     *
     * @return
     */
    public TableDataInfo getRegisterNumByOpinion(HashMap<String, Object> queryParam) {
        List<LinkedHashMap<String, Object>> result = new ArrayList<>();
        HashMap<String, Object> firmNameQuery =getRegisterQuery(queryParam);
        startPage(queryParam);
        List<AssuranceBusinessDataRegisterSignature> list = assuranceBusinessDataRegisterSignatureMapper.selectRegisterListByGroup(firmNameQuery);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<String> registrationCertificateNoList = new ArrayList<>();
        getRegisterTableData(list,result,registrationCertificateNoList);
        HashMap<String, Object> query = new HashMap<>();
        query.put("registrationCertificateNoList", registrationCertificateNoList);
        query.put("startTime", queryParam.get("startTime").toString());
        query.put("endTime", queryParam.get("endTime").toString());
        List<HashMap<String, Object>> reportList = assuranceBusinessDataReportMapper.getRegisterNumByOpinion(query);
        getRegistrantOpinionData(reportList,result);
        tableDataInfo.setRows(result);
        return tableDataInfo;
    }

    /**
     * 获取 验资业务-按所统计 报表
     *
     * @return
     */
    public TableDataInfo getAssuranceNumBySecurities(HashMap<String, Object> queryParam) {
        List<LinkedHashMap<String, Object>> result = new ArrayList<>();
        HashMap<String, Object> firmNameQuery = getFirmNameQuery(queryParam);
        startPage(queryParam);
        List<AntiCounterfeitingRegisteredOffice> list = antiCounterfeitingRegisteredOfficeMapper.selectReportOffice(firmNameQuery);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<Long> officeIdList = new ArrayList<>();
        getFirmNameTableData(list,result,officeIdList);
        HashMap<String, Object> query = new HashMap<>();
        query.put("firmName", officeIdList);
        query.put("startTime", queryParam.get("startTime").toString());
        query.put("endTime", queryParam.get("endTime").toString());
        List<HashMap<String, Object>> reportList = assuranceBusinessDataReportMapper.getAssuranceNumBySecurities(query);
        getOfficeSecuritiesData(reportList,result);
        tableDataInfo.setRows(result);
        return tableDataInfo;
    }

    /**
     * 验资业务-按CPA统计 报表
     *
     * @return
     */
    public TableDataInfo getRegisterNumBySecurities(HashMap<String, Object> queryParam) {
        List< LinkedHashMap<String, Object>> result = new ArrayList<>();
        HashMap<String, Object> firmNameQuery =getRegisterQuery(queryParam);
        startPage(queryParam);
        List<AssuranceBusinessDataRegisterSignature> list = assuranceBusinessDataRegisterSignatureMapper.selectRegisterListByGroup(firmNameQuery);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<String> registrationCertificateNoList = new ArrayList<>();
        getRegisterTableData(list,result,registrationCertificateNoList);
        HashMap<String, Object> query = new HashMap<>();
        query.put("registrationCertificateNoList", registrationCertificateNoList);
        query.put("startTime", queryParam.get("startTime").toString());
        query.put("endTime", queryParam.get("endTime").toString());
        List<HashMap<String, Object>> reportList = assuranceBusinessDataReportMapper.getRegisterNumBySecurities(query);
        getRegistrantSecuritiesData(reportList,result);
        tableDataInfo.setRows(result);
        return tableDataInfo;
    }

    /**
     * 获取每个事务所报备类型数据
     *
     * @param
     * @return
     */
    public void getOfficeReportTypeData(List<HashMap<String, Object>> reportList, List<LinkedHashMap<String, Object>> result) {
        for(int i=0;i<result.size();i++){
            LinkedHashMap<String, Object> map = result.get(i);
            getReportTypeMap(map);
            getReportTypeOfficeResultData(reportList,map,1);
        }

    }
    /**
     * 获取每个会计师报备类型数据
     *
     * @param
     * @return
     */
    public void getRegistrantReportTypeData(List<HashMap<String, Object>> reportList,  List< LinkedHashMap<String, Object>>  result ) {
        for(int i=0;i<result.size();i++) {
            LinkedHashMap<String, Object> map =result.get(i);
            getReportTypeMap(map);
            getReportTypeOfficeResultData(reportList,map,2);
        }
    }


    public void getOfficeReportTypeDataOld(HashMap<String, Object> query, LinkedHashMap<String, Object> map) {

        map.put("sscharge",  "-");
        map.put("ssnumber",  "-");
        map.put("ssprice",  "-");
        map.put("ybcharge",  "-");
        map.put("ybnumber",  "-");
        map.put("ybprice",  "-");
        map.put("gycharge",  "-");
        map.put("gynum",  "-");
        map.put("gyprice",  "-");
        map.put("sycharge",  "-");
        map.put("synum",  "-");
        map.put("syprice",  "-");
        map.put("shxscharge",  "-");
        map.put("shxsnum",  "-");
        map.put("shxsprice",  "-");
        map.put("shnjcharge",  "-");
        map.put("shnjnum",  "-");
        map.put("shnjprice",  "-");
        map.put("zxcharge",  "-");
        map.put("zxnum",  "-");
        map.put("zxprice",  "-");
        map.put("yzcharge",  "-");
        map.put("yznum",  "-");
        map.put("yzprice",  "-");
        map.put("qtcharge",  "-");
        map.put("qtnum",  "-");
        map.put("qtprice",  "-");
        List<HashMap<String, Object>> list = assuranceBusinessDataReportMapper.getAssuranceNumByType(query);
        Double allCharge = 0.0;
        Double allNum = 0.0;
        Double allPrice;
        for (int i = 0; i < list.size(); i++) {
            HashMap<String, Object> item = list.get(i);
            Object chargeO = item.get("charge");
            Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
            allCharge = allCharge + charge;
            Object numO = item.get("num");
            Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
            allNum = allNum + num;
            Object priceO = item.get("price");
            Double price = priceO == null ? 0L : Double.parseDouble(priceO.toString());
            String typeName = item.get("report_type").toString();
            if ("上市公司审计".equals(typeName)) {
                map.put("sscharge", charge);
                map.put("ssnumber", num);
                map.put("ssprice", price);
            }
            if ("一般企业审计".equals(typeName)) {
                map.put("ybcharge", charge);
                map.put("ybnumber", num);
                map.put("ybprice", price);
            }
            if ("国有大型企业审计".equals(typeName)) {
                map.put("gycharge", charge);
                map.put("gynum", num);
                map.put("gyprice", price);
            }
            if ("事业单位审计".equals(typeName)) {
                map.put("sycharge", charge);
                map.put("synum", num);
                map.put("syprice", price);
            }
            if ("上市公司新三板企业审计".equals(typeName)) {
                map.put("shxscharge", charge);
                map.put("shxsnum", num);
                map.put("shxsprice", price);
            }
            if ("上市公司内控鉴证业务".equals(typeName)) {
                map.put("shnjcharge", charge);
                map.put("shnjnum", num);
                map.put("shnjprice", price);
            }
            if ("专项审计业务".equals(typeName)) {
                map.put("zxcharge", charge);
                map.put("zxnum", num);
                map.put("zxprice", price);
            }
            if ("验资业务".equals(typeName)) {
                map.put("yzcharge", charge);
                map.put("yznum", num);
                map.put("yzprice", price);
            } else if ("其它".equals(typeName)) {
                map.put("qtcharge", charge);
                map.put("qtnum", num);
                map.put("qtprice", price);
            }
        }
        if (allNum > 0) {
            allPrice = new BigDecimal(allCharge / allNum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        } else {
            allPrice = allCharge;
        }
        map.put("allCharge", allCharge);
        map.put("allNum", allNum);
        map.put("allPrice", allPrice);

    }


    private void getReportTypeMap(LinkedHashMap<String, Object> map){
        map.put("sscharge", "-");
        map.put("ssnumber", "-");
        map.put("ssprice", "-");
        map.put("ybcharge", "-");
        map.put("ybnumber", "-");
        map.put("ybprice", "-");
        map.put("gycharge", "-");
        map.put("gynum", "-");
        map.put("gyprice", "-");
        map.put("sycharge", "-");
        map.put("synum", "-");
        map.put("syprice", "-");
        map.put("shxscharge", "-");
        map.put("shxsnum", "-");
        map.put("shxsprice", "-");
        map.put("shnjcharge", "-");
        map.put("shnjnum", "-");
        map.put("shnjprice", "-");
        map.put("zxcharge", "-");
        map.put("zxnum", "-");
        map.put("zxprice", "-");
        map.put("yzcharge", "-");
        map.put("yznum", "-");
        map.put("yzprice", "-");
        map.put("qtcharge", "-");
        map.put("qtnum", "-");
        map.put("qtprice", "-");
    }

    /**
     * 具体 ---- 获取每个事务所报备类型数据
     * @param reportList
     * @param map
     */
    private void getReportTypeOfficeResultData(List<HashMap<String, Object>> reportList, LinkedHashMap<String, Object> map,int type){
        String name ="";
        String nameNo="" ;
        if(type == 1){
            name = map.get("firmName").toString();
        }else{
            name =  map.get("registrantName").toString();
            nameNo =  map.get("registrationCertificateNo").toString();
        }
        Double allCharge = 0.0;
        Double allNum = 0.0;
        Double allPrice = 0.0;
        for (int i = 0; i < reportList.size(); i++) {
            HashMap<String, Object> item = reportList.get(i);
            if(type == 1 && (name.equals(item.get("firm_name").toString()))){
                Object chargeO = item.get("charge");
                Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
                allCharge = allCharge + charge;
                Object numO = item.get("num");
                Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
                allNum = allNum + num;
                Object priceO = item.get("price");
                Double price = priceO == null ? 0L : Double.parseDouble(priceO.toString());
                String typeName = item.get("report_type").toString();
                if ("上市公司审计".equals(typeName)) {
                    map.put("sscharge", charge);
                    map.put("ssnumber", num);
                    map.put("ssprice", price);
                }
                if ("一般企业审计".equals(typeName)) {
                    map.put("ybcharge", charge);
                    map.put("ybnumber", num);
                    map.put("ybprice", price);
                }
                if ("国有大型企业审计".equals(typeName)) {
                    map.put("gycharge", charge);
                    map.put("gynum", num);
                    map.put("gyprice", price);
                }
                if ("事业单位审计".equals(typeName)) {
                    map.put("sycharge", charge);
                    map.put("synum", num);
                    map.put("syprice", price);
                }
                if ("上市公司新三板企业审计".equals(typeName)) {
                    map.put("shxscharge", charge);
                    map.put("shxsnum", num);
                    map.put("shxsprice", price);
                }
                if ("上市公司内控鉴证业务".equals(typeName)) {
                    map.put("shnjcharge", charge);
                    map.put("shnjnum", num);
                    map.put("shnjprice", price);
                }
                if ("专项审计业务".equals(typeName)) {
                    map.put("zxcharge", charge);
                    map.put("zxnum", num);
                    map.put("zxprice", price);
                }
                if ("验资业务".equals(typeName)) {
                    map.put("yzcharge", charge);
                    map.put("yznum", num);
                    map.put("yzprice", price);
                } else if ("其它".equals(typeName)) {
                    map.put("qtcharge", charge);
                    map.put("qtnum", num);
                    map.put("qtprice", price);
                }
            }
            if(type == 2 &&  name.equals(item.get("registrant_name").toString()) && nameNo.equals(item.get("registration_certificate_no").toString()) ){
                Object chargeO = item.get("charge");
                Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
                allCharge = allCharge + charge;
                Object numO = item.get("num");
                Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
                allNum = allNum + num;
                Object priceO = item.get("price");
                Double price = priceO == null ? 0L : Double.parseDouble(priceO.toString());
                String typeName = item.get("report_type").toString();
                if ("上市公司审计".equals(typeName)) {
                    map.put("sscharge", charge);
                    map.put("ssnumber", num);
                    map.put("ssprice", price);
                }
                if ("一般企业审计".equals(typeName)) {
                    map.put("ybcharge", charge);
                    map.put("ybnumber", num);
                    map.put("ybprice", price);
                }
                if ("国有大型企业审计".equals(typeName)) {
                    map.put("gycharge", charge);
                    map.put("gynum", num);
                    map.put("gyprice", price);
                }
                if ("事业单位审计".equals(typeName)) {
                    map.put("sycharge", charge);
                    map.put("synum", num);
                    map.put("syprice", price);
                }
                if ("上市公司新三板企业审计".equals(typeName)) {
                    map.put("shxscharge", charge);
                    map.put("shxsnum", num);
                    map.put("shxsprice", price);
                }
                if ("上市公司内控鉴证业务".equals(typeName)) {
                    map.put("shnjcharge", charge);
                    map.put("shnjnum", num);
                    map.put("shnjprice", price);
                }
                if ("专项审计业务".equals(typeName)) {
                    map.put("zxcharge", charge);
                    map.put("zxnum", num);
                    map.put("zxprice", price);
                }
                if ("验资业务".equals(typeName)) {
                    map.put("yzcharge", charge);
                    map.put("yznum", num);
                    map.put("yzprice", price);
                } else if ("其它".equals(typeName)) {
                    map.put("qtcharge", charge);
                    map.put("qtnum", num);
                    map.put("qtprice", price);
                }
            }
        }
        if (allNum > 0) {
            allPrice = new BigDecimal(allCharge / allNum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        } else {
            allPrice = allCharge;
        }
        map.put("allCharge", allCharge);
        map.put("allNum", allNum);
        map.put("allPrice", allPrice);

    }

    public void getRegistrantReportTypeDataOld(HashMap<String, Object> query, LinkedHashMap<String, Object> map) {
        map.put("sscharge",  "-");
        map.put("ssnumber",  "-");
        map.put("ssprice",  "-");
        map.put("ybcharge",  "-");
        map.put("ybnumber",  "-");
        map.put("ybprice",  "-");
        map.put("gycharge",  "-");
        map.put("gynum",  "-");
        map.put("gyprice",  "-");
        map.put("sycharge",  "-");
        map.put("synum",  "-");
        map.put("syprice",  "-");
        map.put("shxscharge",  "-");
        map.put("shxsnum",  "-");
        map.put("shxsprice",  "-");
        map.put("shnjcharge",  "-");
        map.put("shnjnum",  "-");
        map.put("shnjprice",  "-");
        map.put("zxcharge",  "-");
        map.put("zxnum",  "-");
        map.put("zxprice",  "-");
        map.put("yzcharge",  "-");
        map.put("yznum",  "-");
        map.put("yzprice",  "-");
        map.put("qtcharge",  "-");
        map.put("qtnum",  "-");
        map.put("qtprice",  "-");
        List<HashMap<String, Object>> list = assuranceBusinessDataReportMapper.getRegisterNumByType(query);
        Double allCharge = 0.0;
        Double allNum = 0.0;
        Double allPrice;
        for (int i = 0; i < list.size(); i++) {
            HashMap<String, Object> item = list.get(i);
            Object chargeO = item.get("charge");
            Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
            allCharge = allCharge + charge;
            Object numO = item.get("num");
            Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
            allNum = allNum + num;
            Object priceO = item.get("price");
            Double price = priceO == null ? 0L : Double.parseDouble(priceO.toString());
            String typeName = item.get("report_type").toString();
            if ("上市公司审计".equals(typeName)) {
                map.put("sscharge", charge);
                map.put("ssnumber", num);
                map.put("ssprice", price);
            }
            if ("一般企业审计".equals(typeName)) {
                map.put("ybcharge", charge);
                map.put("ybnumber", num);
                map.put("ybprice", price);
            }
            if ("国有大型企业审计".equals(typeName)) {
                map.put("gycharge", charge);
                map.put("gynum", num);
                map.put("gyprice", price);
            }
            if ("事业单位审计".equals(typeName)) {
                map.put("sycharge", charge);
                map.put("synum", num);
                map.put("syprice", price);
            }
            if ("上市公司新三板企业审计".equals(typeName)) {
                map.put("shxscharge", charge);
                map.put("shxsnum", num);
                map.put("shxsprice", price);
            }
            if ("上市公司内控鉴证业务".equals(typeName)) {
                map.put("shnjcharge", charge);
                map.put("shnjnum", num);
                map.put("shnjprice", price);
            }
            if ("专项审计业务".equals(typeName)) {
                map.put("zxcharge", charge);
                map.put("zxnum", num);
                map.put("zxprice", price);
            }
            if ("验资业务".equals(typeName)) {
                map.put("yzcharge", charge);
                map.put("yznum", num);
                map.put("yzprice", price);
            } else if ("其它".equals(typeName)) {
                map.put("qtcharge", charge);
                map.put("qtnum", num);
                map.put("qtprice", price);
            }
        }
        if (allNum > 0) {
            allPrice = new BigDecimal(allCharge / allNum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        } else {
            allPrice = allCharge;
        }
        map.put("allCharge", allCharge);
        map.put("allNum", allNum);
        map.put("allPrice", allPrice);

    }

    /**
     * 获取每个事务所审计意见数据
     *
     * @param
     * @return
     */
    public void getOfficeOpinionData(List<HashMap<String, Object>> reportList, List<LinkedHashMap<String, Object>> result) {
        for(int i=0;i<result.size();i++){
            LinkedHashMap<String, Object> map = result.get(i);
            getOpinionMap(map);
            getOfficeOpinionResultData(reportList,map);
        }
    }
    private void getOpinionMap(LinkedHashMap<String, Object> map){
        map.put("bznum", "-");
        map.put("bzcharge", "-");
        map.put("dqnum", "-");
        map.put("dqcharge", "-");
        map.put("blnum", "-");
        map.put("blcharge", "-");
        map.put("fdnum", "-");
        map.put("fdcharge", "-");
        map.put("wfnum", "-");
        map.put("wfcharge", "-");
        map.put("qtnum", "-");
        map.put("qtcharge", "-");
    }
    private void getOfficeOpinionResultData(List<HashMap<String, Object>> reportList,LinkedHashMap<String, Object> map){
        String firmName = map.get("firmName").toString();
        for (int i = 0; i < reportList.size(); i++) {
            HashMap<String, Object> item = reportList.get(i);
            if(firmName.equals(item.get("firm_name").toString())){
                Object chargeO = item.get("charge");
                Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
                Object numO = item.get("num");
                Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
                String typeName = item.get("opinion_type").toString();
                if ("无保留意见".equals(typeName)) {
                    map.put("bzcharge", charge);
                    map.put("bznum", num);
                }
                if ("带强调事项端无保留".equals(typeName)) {
                    map.put("dqcharge", charge);
                    map.put("dqnum", num);
                }
                if ("保留意见".equals(typeName)) {
                    map.put("blcharge", charge);
                    map.put("blnum", num);
                }
                if ("否定意见".equals(typeName)) {
                    map.put("fdcharge", charge);
                    map.put("fdnum", num);
                }
                if ("无法表示意见".equals(typeName)) {
                    map.put("wfnum", num);
                    map.put("wfcharge", charge );
                }
                if ("其他".equals(typeName)) {
                    map.put("qtcharge", charge);
                    map.put("qtnum", num);
                }
            }
        }
    }
    public void getOfficeOpinionDataOld(HashMap<String, Object> query, LinkedHashMap<String, Object> result) {
        result.put("bznum", "-");
        result.put("bzcharge", "-");
        result.put("dqnum", "-");
        result.put("dqcharge", "-");
        result.put("blnum", "-");
        result.put("blcharge", "-");
        result.put("fdnum", "-");
        result.put("fdcharge", "-");
        result.put("wfnum", "-");
        result.put("wfcharge", "-");
        result.put("qtnum", "-");
        result.put("qtcharge", "-");
        List<HashMap<String, Object>> list = assuranceBusinessDataReportMapper.getAssuranceNumByOpinion(query);
        for (int i = 0; i < list.size(); i++) {
            HashMap<String, Object> item = list.get(i);
            Object chargeO = item.get("charge");
            Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
            Object numO = item.get("num");
            Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
            String typeName = item.get("opinion_type").toString();
            if ("无保留意见".equals(typeName)) {
                result.put("bzcharge", charge);
                result.put("bznum", num);
            }
            if ("带强调事项端无保留".equals(typeName)) {
                result.put("dqcharge", charge);
                result.put("dqnum", num);
            }
            if ("保留意见".equals(typeName)) {
                result.put("blcharge", charge);
                result.put("blnum", num);
            }
            if ("否定意见".equals(typeName)) {
                result.put("fdcharge", charge);
                result.put("fdnum", num);
            }
            if ("无法表示意见".equals(typeName)) {
                result.put("wfnum", num);
                result.put("wfcharge", charge );
            }
            if ("其他".equals(typeName)) {
                result.put("qtcharge", charge);
                result.put("qtnum", num);
            }
        }
    }

    /**
     * 获取每个会计师审计意见数据
     *
     * @param
     * @return
     */
    public void getRegistrantOpinionData(List<HashMap<String, Object>> reportList, List<LinkedHashMap<String, Object>> result) {
        for(int i=0;i<result.size();i++){
            LinkedHashMap<String, Object> map = result.get(i);
            getOpinionMap(map);
            getOpinionRegisterResultData(reportList,map);
        }


    }
   private void getOpinionRegisterResultData(List<HashMap<String, Object>> reportList, LinkedHashMap<String, Object> map){
        String registrantName = map.get("registrantName").toString();
       String registrationCertificateNo = map.get("registrationCertificateNo").toString();
       for (int i = 0; i < reportList.size(); i++) {
           HashMap<String, Object> item = reportList.get(i);
           if(registrantName.equals(item.get("registrant_name").toString()) && registrationCertificateNo.equals(item.get("registration_certificate_no").toString())){
               Object chargeO = item.get("charge");
               Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
               Object numO = item.get("num");
               Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
               String typeName = item.get("opinion_type").toString();
               if ("无保留意见".equals(typeName)) {
                   map.put("bzcharge", charge);
                   map.put("bznum", num);
               }
               if ("带强调事项端无保留".equals(typeName)) {
                   map.put("dqcharge", charge);
                   map.put("dqnum", num);
               }
               if ("保留意见".equals(typeName)) {
                   map.put("blcharge", charge);
                   map.put("blnum", num);
               }
               if ("否定意见".equals(typeName)) {
                   map.put("fdcharge", charge);
                   map.put("fdnum", num);
               }
               if ("无法表示意见".equals(typeName)) {
                   map.put("wfnum",num );
                   map.put("wfcharge",charge );
               }
               if ("其他".equals(typeName)) {
                   map.put("qtcharge", charge);
                   map.put("qtnum", num);
               }
           }
       }
   }
    /**
     * 获取每个会计师审计意见数据
     *
     * @param query
     * @return
     */
    public void getRegistrantOpinionDataOld(HashMap<String, Object> query,LinkedHashMap<String, Object> result) {

        result.put("bznum", "-");
        result.put("bzcharge", "-");
        result.put("dqnum", "-");
        result.put("dqcharge", "-");
        result.put("blnum", "-");
        result.put("blcharge", "-");
        result.put("fdnum", "-");
        result.put("fdcharge", "-");
        result.put("wfnum", "-");
        result.put("wfcharge", "-");
        result.put("qtnum", "-");
        result.put("qtcharge", "-");
        List<HashMap<String, Object>> list = assuranceBusinessDataReportMapper.getRegisterNumByOpinion(query);
        for (int i = 0; i < list.size(); i++) {
            HashMap<String, Object> item = list.get(i);
            Object chargeO = item.get("charge");
            Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
            Object numO = item.get("num");
            Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
            String typeName = item.get("opinion_type").toString();
            if ("无保留意见".equals(typeName)) {
                result.put("bzcharge", charge);
                result.put("bznum", num);
            }
            if ("带强调事项端无保留".equals(typeName)) {
                result.put("dqcharge", charge);
                result.put("dqnum", num);
            }
            if ("保留意见".equals(typeName)) {
                result.put("blcharge", charge);
                result.put("blnum", num);
            }
            if ("否定意见".equals(typeName)) {
                result.put("fdcharge", charge);
                result.put("fdnum", num);
            }
            if ("无法表示意见".equals(typeName)) {
                result.put("wfnum",num );
                result.put("wfcharge",charge );
            }
            if ("其他".equals(typeName)) {
                result.put("qtcharge", charge);
                result.put("qtnum", num);
            }
        }
    }

    /**
     * 获取每个事务所验资业务数据
     *
     * @param
     * @return
     */
    public void getOfficeSecuritiesData(List<HashMap<String, Object>> reportList,List<LinkedHashMap<String, Object>> result) {
        for(int i=0;i<result.size();i++){
            LinkedHashMap<String, Object> map = result.get(i);
            getSecuritiesMap(map);
            getOfficeSecuritiesResultData(reportList,map);
        }

    }

    private void getSecuritiesMap(LinkedHashMap<String, Object> map){
        map.put("zqnum", "-");
        map.put("zqcharge", "-");
        map.put("fzqnum", "-");
        map.put("fzqcharge", "-");
    }

    private void getOfficeSecuritiesResultData(List<HashMap<String, Object>> reportList, LinkedHashMap<String, Object> map){
        String firmName = map.get("firmName").toString();
        for (int i = 0; i < reportList.size(); i++) {
            HashMap<String, Object> item = reportList.get(i);
            if(firmName.equals(item.get("firm_name").toString())){
                Object chargeO = item.get("charge");
                Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
                Object numO = item.get("num");
                Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
                String typeName = item.get("is_securities_business").toString();
                if ("是".equals(typeName)) {
                    map.put("zqcharge", charge);
                    map.put("zqnum", num);
                }
                if ("否".equals(typeName)) {
                    map.put("fzqcharge", charge);
                    map.put("fzqnum", num);
                }
            }

        }
    }

    /**
     * 获取每个会计师验资业务数据
     *
     * @param
     * @return
     */
    public void getRegistrantSecuritiesData(List<HashMap<String, Object>> reportList, List<LinkedHashMap<String, Object>> result) {
        for(int i=0;i<result.size();i++){
            LinkedHashMap<String, Object> map = result.get(i);
            getSecuritiesMap(map);
            getRegistrSecuritiesResultData(reportList,map);
        }


    }
    private void getRegistrSecuritiesResultData(List<HashMap<String, Object>> reportList,LinkedHashMap<String, Object> map){
        String registrantName = map.get("registrantName").toString();
        String registrationCertificateNo = map.get("registrationCertificateNo").toString();
        for (int i = 0; i < reportList.size(); i++) {
            HashMap<String, Object> item = reportList.get(i);
            if(registrantName.equals(item.get("registrant_name").toString())  && registrationCertificateNo.equals(item.get("registration_certificate_no").toString())){
                Object chargeO = item.get("charge");
                Double charge = chargeO == null ? 0L : Double.parseDouble(chargeO.toString());
                Object numO = item.get("num");
                Double num = numO == null ? 0L : Double.parseDouble(numO.toString());
                String typeName = item.get("is_securities_business").toString();
                if ("是".equals(typeName)) {
                    map.put("zqcharge", charge);
                    map.put("zqnum", num);
                }
                if ("否".equals(typeName)) {
                    map.put("fzqcharge", charge);
                    map.put("fzqnum", num);
                }
            }
        }
    }

    /**
     * 根据客户获取报告的信息与事务所，注册师
     *更换事务所统计
     * @return
     */
    public TableDataInfo selectCustomerReportData(HashMap<String, Object> query) {
        startPage(query);
        List<HashMap<String, Object>> list = assuranceBusinessDataReportMapper.selectOfficeDataByCustomer(query);
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        TableDataInfo tableDataInfo = getDataTable(list);
        List<String> licenseList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            HashMap<String, Object> item = list.get(i);
            LinkedHashMap<String, Object> result = new LinkedHashMap<>();
            result.put("id",i+1);
            result.put("customer_business_license",item.get("customer_business_license"));
            result.put("customer_name",item.get("customer_name"));
            licenseList.add(item.get("customer_name").toString());

            resultList.add(result);
        }
        HashMap<String, Object> officeQuery = new HashMap<>();
        officeQuery.put("licenseList",licenseList);
        List<HashMap<String, Object>> officeDataList = assuranceBusinessDataReportMapper.selectOfficeCustomerData(officeQuery);
        getCustomerReportData(officeDataList,resultList);
        tableDataInfo.setRows(resultList);
        return tableDataInfo;
    }

    private void  getCustomerReportData(List<HashMap<String, Object>> officeDataList,List<LinkedHashMap<String, Object>> resultList){
        for(int i=0;i<resultList.size();i++){
            LinkedHashMap<String, Object> result =resultList.get(i);
            String customerName = result.get("customer_name").toString();
            int k = 0;
            for(int y=0;y<officeDataList.size();y++){
                HashMap<String, Object> item = officeDataList.get(y);
                if(customerName.equals(item.get("customer_name"))){
                    if(k == 0){
                        result.put("office_number_one",item.get("practice_certificate_no").toString());
                        result.put("firm_name_one",item.get("firm_name").toString());
                    }
                    if(k == 1){
                        result.put("office_number_two",item.get("practice_certificate_no").toString());
                        result.put("firm_name_two",item.get("firm_name").toString());
                    }
                    k++;
                }
                if(k>=2){
                    break;
                }
            }
        }
    }

    /**
     * 根据注册师获取报告的信息与事务所
     *根据注师汇总报告-报告数量畸多
     * @return
     */
    public TableDataInfo selectRegisterReportData(HashMap<String, Object> query) {
        startPage(query);
        List<HashMap<String, Object>> list = assuranceBusinessDataReportMapper.selectRegisterReportData(query);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<String> firmNameList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            HashMap<String, Object> item = list.get(i);
            LinkedHashMap<String, Object> result = new LinkedHashMap<>();
            result.put("id",i+1);
            result.put("registrant_name",item.get("registrant_name"));
            result.put("registration_certificate_no",item.get("registration_certificate_no"));
            result.put("report_code",item.get("report_code"));
            result.put("filing_time",item.get("filing_time"));
            result.put("report_type",item.get("report_type"));
            result.put("customer_business_license",item.get("customer_business_license"));
            result.put("customer_name",item.get("customer_name"));
            result.put("report_no_clean",item.get("report_no_clean"));
            result.put("opinion_type",item.get("opinion_type"));
            result.put("audit_year",item.get("audit_year"));
            result.put("charge_amount",item.get("charge_amount"));
            result.put("report_time",item.get("report_time"));
            result.put("office_number",item.get("office_number"));
            result.put("firm_name",item.get("firm_name"));
            result.put("registrant_name_one", "-");
            result.put("registration_certificate_no_one", "-");
            result.put("registrant_name_two", "-");
            result.put("registration_certificate_no_two", "-");
            String firmName = item.get("firm_name").toString();
            firmNameList.add(firmName);
            resultList.add(result);
        }

        HashMap<String, Object> registerquery = new HashMap<>();
        registerquery.put("firmNameList", firmNameList);
        List<HashMap<String, Object>> registerlist = assuranceBusinessDataRegisterSignatureMapper.selectRegisterListByOffice(registerquery);
        getRegisterReportFirmNameData(resultList,registerlist);
        tableDataInfo.setRows(resultList);
        return tableDataInfo;
    }

    private void getRegisterReportFirmNameData(List<LinkedHashMap<String, Object>> resultList,List<HashMap<String, Object>> registerlist){
        for(int i=0;i<resultList.size();i++){
            LinkedHashMap<String, Object> result = resultList.get(i);
            String firmName = result.get("firm_name").toString();
            int k=0;
            for(int y=0;y<registerlist.size();y++){
                HashMap<String, Object> item = registerlist.get(y);
                if(firmName.equals(item.get("firm_name").toString())){
                    if (k == 0) {
                        result.put("registrant_name_one", item.get("registrant_name").toString());
                        result.put("registration_certificate_no_one", item.get("registration_certificate_no").toString());
                    }
                    if (k == 1) {
                        result.put("registrant_name_two", item.get("registrant_name").toString());
                        result.put("registration_certificate_no_two", item.get("registration_certificate_no").toString());
                    }
                    k++;
                }
                if(k>=2){
                    break;
                }
            }

        }
    }

    /**
     * 封装报表数据
     *
     * @param list
     * @return
     */
    private TableDataInfo getDataTable(List<?> list) {
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(new PageInfo(list).getTotal());
        return rspData;
    }

    /**
     * 分页
     *
     * @param queryParam
     */
    private void startPage(HashMap<String, Object> queryParam) {
        Object pageNumO = queryParam.get("pageNum");
        Object pageSizeO = queryParam.get("pageSize");
        PageHelper.startPage(pageNumO == null ? 1 : NumberUtils.toInt(pageNumO.toString()), pageSizeO == null ? 10 : NumberUtils.toInt(pageSizeO.toString()));
    }
}
